package com.influxdb.test;

import com.alibaba.fastjson2.JSON;
import com.influxdb.annotations.Column;
import com.influxdb.annotations.Measurement;
import com.influxdb.client.InfluxDBClient;
import com.influxdb.client.InfluxDBClientFactory;
import com.influxdb.client.QueryApi;
import com.influxdb.client.WriteApi;
import com.influxdb.client.domain.InfluxQLQuery;
import com.influxdb.client.domain.WritePrecision;
import com.influxdb.query.FluxRecord;
import com.influxdb.query.FluxTable;
import com.influxdb.query.InfluxQLQueryResult;
import lombok.Data;

import java.time.Instant;
import java.util.List;
import java.util.Map;

//  influxdb-client-java 测试
public class DevicePojoTest1 {
    private static String org = "testorg";
    private static String backet = "testbicket";
    private static char[] token = "sb60tCsLUfC7zHWU84V0L3GLlNp_FkQDgVLsTiTfIuIT193Z7wceG9Chatr2CaUEVq53o2vgqLn4wo_EHiS-LA==".toCharArray();
    private static InfluxDBClient influxDBClient = InfluxDBClientFactory.create("http://127.0.0.1:8086", token,org,backet);

    public static void main(String[] args) {
        //insert();
        //asyncInsert();
        getData();
        influxDBClient.close();
    }



    public static void getCount() {

    }

    public static void getData() {
        String location = "A";
        String flux = "from(bucket: \"testbicket\")\n" +
                "  |> range(start: -2h)\n" +
                "  |> filter(fn: (r) => r[\"_measurement\"] == \"temperature\")\n" +
                //"  |> filter(fn: (r) => r[\"location\"] == \""+ location +"\")\n" +
                "  |> filter(fn: (r) => r[\"location\"] == \"A\" or r[\"location\"] == \"B\" or r[\"location\"] == \"C\")\n" +
                "  |> aggregateWindow(every: 10s, fn: mean, createEmpty: false)\n" +
                "  |> yield(name: \"mean\")";

        InfluxDBClient influxDBClient = InfluxDBClientFactory.create("http://127.0.0.1:8086", token, org);
        QueryApi queryApi = influxDBClient.getQueryApi();
        String s = queryApi.queryRaw(flux);
        System.out.println("s=" + s);
        List<FluxTable> res = queryApi.query(flux);// flux查询
        System.out.println(res.size());
        for (FluxTable re : res) {
            for (FluxRecord record : re.getRecords()) {
                Map<String, Object> values = record.getValues();
                System.out.println(values);
            }
        }
        System.out.println("============================= InfluxQL查询 =============================");
        // sql语句查询
        // 创建 InfluxQL 查询对象
        InfluxQLQuery influxQLQuery = new InfluxQLQuery("SELECT location,value,timestamp FROM temperature WHERE time > now() - 1h GROUP BY location", backet);
        // 查询所有数据
        influxQLQuery = new InfluxQLQuery("SELECT location,value,timestamp FROM temperature WHERE time > now() - 6h GROUP BY location", backet);
        // 每个序列取一条数据
        influxQLQuery = new InfluxQLQuery("SELECT location,value,timestamp FROM temperature WHERE time > now() - 6h GROUP BY location LIMIT 1", backet);
        // 每个序列倒序取一条数据 time字段固定的，自定义时间倒序会报错
        influxQLQuery = new InfluxQLQuery("SELECT location,value,timestamp FROM temperature WHERE time > now() - 6h GROUP BY location ORDER BY time DESC LIMIT 1", backet);
        InfluxQLQueryResult result = influxDBClient.getInfluxQLQueryApi().query(influxQLQuery);
        if (result != null){// 空的时候为Null
            for (InfluxQLQueryResult.Result resultResult : result.getResults()) {
                for (InfluxQLQueryResult.Series series : resultResult.getSeries()) {
                    for (InfluxQLQueryResult.Series.Record record : series.getValues()) {
                        //System.out.println(record.getValueByKey("time") + ": " + record.getValueByKey("first"));
                        System.out.println(JSON.toJSONString(record));
                    }
                }
            }
        }

        influxDBClient.close();

    }

    // 同步写入
    public static void insert() {
        // 方法1：WriteApiBlocking 写入
        /*
        WriteApiBlocking writeApiBlocking = influxDBClient.getWriteApiBlocking();
        writeApiBlocking.writeRecord(WritePrecision.MS,"temperature,location=A value=25");*/

        // 方法2：Point 写入
        /*
        WriteApiBlocking writeApiBlocking = influxDBClient.getWriteApiBlocking();
        Point point = Point.measurement("temperature")
                .addTag("location", "B")
                .addField("value", 30.5)
                .time(Instant.now(), WritePrecision.MS);
        System.out.println(point.toLineProtocol());
        writeApiBlocking.writePoint(point);*/

        // 方法3：实体pojo 写入
        DemoPojo demoPojo = new DemoPojo();
        demoPojo.setLocation("B");
        demoPojo.setValue(55.5);
        demoPojo.setTimestamp(Instant.now());
        influxDBClient.getWriteApiBlocking().writeMeasurement(WritePrecision.MS,demoPojo);
    }

    // 异步写入
    public static void asyncInsert() {
        WriteApi writeApi = influxDBClient.makeWriteApi();
        DemoPojo demoPojo = new DemoPojo();
        demoPojo.setLocation("C");
        demoPojo.setValue(25.5);
        demoPojo.setTimestamp(Instant.now());
        writeApi.writeMeasurement(WritePrecision.MS,demoPojo);
        writeApi.flush();// 立即刷新
    }

    public static void delete() {

    }

    public static void other(){

    }

    @Data
    @Measurement(name = "temperature")
    public static class DemoPojo{
        /*@Column(measurement = true)
        private String measurement;*/

        @Column(tag = true)
        private String location;

        @Column
        private Double value;

        @Column(timestamp = true)
        private Instant timestamp;
    }
}
